use crate::{
    entity::{
        sys_dept, sys_dict, sys_dict_data, sys_login_log, sys_operate_log, sys_post, sys_resource,
        sys_role, sys_role_resource, sys_user, sys_user_post, sys_user_role,
    },
    password,
};
use ane_macros::create_table;
use sea_orm::{
    ActiveModelTrait, ColumnTrait, ConnectionTrait, DbConn, EntityTrait, IntoActiveModel,
    QueryFilter, Schema, Set, TransactionTrait,
};

pub struct Mutation;

impl Mutation {
    /// 创建相关表格
    ///
    /// 简单判断表格是否存在，不存在则创建
    pub async fn init_db(db: &DbConn) -> Result<(), sea_orm::DbErr> {
        let builder = db.get_database_backend();
        let schema = Schema::new(builder);
        let txn = db.begin().await?;
        create_table!(sys_dept, txn, builder, schema);
        create_table!(sys_user, txn, builder, schema);
        create_table!(sys_role, txn, builder, schema);
        create_table!(sys_user_role, txn, builder, schema);
        create_table!(sys_post, txn, builder, schema);
        create_table!(sys_user_post, txn, builder, schema);
        create_table!(sys_resource, txn, builder, schema);
        create_table!(sys_role_resource, txn, builder, schema);
        create_table!(sys_dict_data, txn, builder, schema);
        create_table!(sys_dict, txn, builder, schema);
        create_table!(sys_login_log, txn, builder, schema);
        create_table!(sys_operate_log, txn, builder, schema);
        Self::init_dept(&txn).await?;
        Self::add_super_user(&txn).await?;
        txn.commit().await?;
        Ok(())
    }

    /// 不存在则创建
    async fn init_dept<C>(db: &C) -> Result<(), sea_orm::DbErr>
    where
        C: ConnectionTrait,
    {
        if sys_dept::Entity::find_by_id(1).one(db).await?.is_none() {
            let model = sys_dept::ActiveModel {
                dept_id: Set(1),
                parent_id: Set(0),
                ancestors: Set("/0/1/".to_string()),
                dept_name: Set("Ane admin".to_string()),
                manager: Set("".to_string()),
                phone: Set("".to_string()),
                email: Set("".to_string()),
                description: Set("".to_string()),
                order_num: Set(0),
                status: Set(true),
                del_flag: Set(false),
                ..Default::default()
            };
            model.insert(db).await?;
        }
        Ok(())
    }

    /// 不存在则添加超级管理员
    /// - username:`admin`
    /// - password:`027027`
    pub async fn add_super_user<C>(db: &C) -> Result<(), sea_orm::DbErr>
    where
        C: ConnectionTrait,
    {
        let admin = sys_user::Entity::find()
            .filter(sys_user::Column::Username.eq("admin"))
            .one(db)
            .await?;
        if let Some(admin) = admin {
            let mut model = admin.into_active_model();
            model.dept_id = Set(1);
            model.del_flag = Set(false);
            model.del_flag = Set(false);
            model.update(db).await?;
        } else {
            let s = sys_user::ActiveModel {
                dept_id: Set(1),
                username: Set("admin".to_owned()),
                nickname: Set("admin".to_owned()),
                avatar: Set("".to_owned()),
                status: Set(true),
                phone: Set("".to_owned()),
                email: Set("".to_owned()),
                remark: Set("".to_owned()),
                sex: Set(0),
                del_flag: Set(false),
                password: Set(password::hash("027027").unwrap()),
                ..Default::default()
            };
            s.insert(db).await?;
        }
        return Ok(());
    }

    /// 初始化超级管理员，存在则重置密码
    /// - username:`admin`
    /// - password:`027027`
    pub async fn init_super_user<C>(db: &C) -> Result<(), sea_orm::DbErr>
    where
        C: ConnectionTrait,
    {
        let admin = sys_user::Entity::find()
            .filter(sys_user::Column::Username.eq("admin"))
            .one(db)
            .await?;
        if let Some(admin) = admin {
            let mut model = admin.into_active_model();
            model.user_id = Set(1);
            model.del_flag = Set(false);
            model.del_flag = Set(false);
            model.password = Set(password::hash("027027").unwrap());
            model.update(db).await?;
        } else {
            let s = sys_user::ActiveModel {
                dept_id: Set(1),
                username: Set("admin".to_owned()),
                nickname: Set("admin".to_owned()),
                avatar: Set("".to_owned()),
                status: Set(true),
                phone: Set("".to_owned()),
                email: Set("".to_owned()),
                remark: Set("".to_owned()),
                sex: Set(0),
                del_flag: Set(false),
                password: Set(password::hash("027027").unwrap()),
                ..Default::default()
            };
            s.insert(db).await?;
        }
        return Ok(());
    }

    pub async fn new_user(
        db: &DbConn,
        dept_id: i32,
        username: String,
        nickname: String,
        password: &str,
    ) -> Result<(), sea_orm::DbErr> {
        let s = sys_user::ActiveModel {
            dept_id: Set(dept_id),
            username: Set(username),
            nickname: Set(nickname),
            avatar: Set("".to_owned()),
            status: Set(false),
            del_flag: Set(false),
            password: Set(password::hash(password).unwrap()),
            ..Default::default()
        };
        let _ = s.insert(db).await?;
        Ok(())
    }
}
